package com.viknix.threadpool.manager.config.executor;

import com.viknix.threadpool.manager.server.dependence.factory.ExecutorFactory;
import com.viknix.threadpool.manager.server.dependence.factory.NameThreadFactory;
import com.viknix.threadpool.manager.server.dependence.util.ClassUtils;
import com.viknix.threadpool.manager.server.dependence.util.ThreadUtils;

import java.util.concurrent.*;

/**
 * @Author: Dongqi
 * @Date: 2021/11/1 10:45
 * @Version 1.0
 * @Description: ConfigExecutor
 */
public class ConfigExecutor {

    private static final Executor DUMP_EXECUTOR = ExecutorFactory.Managed
            .newSingleExecutorService(ClassUtils.getCanonicalName(ConfigExecutor.class),
                    new NameThreadFactory("com.viknix.tpm.config.embedded.dump"));

    private static final ScheduledExecutorService TIMER_EXECUTOR = ExecutorFactory.Managed
            .newScheduledExecutorService(ClassUtils.getCanonicalName(ConfigExecutor.class), 10,
                    new NameThreadFactory("com.viknix.tpm.config.server.timer"));

    private static final ScheduledExecutorService CAPACITY_MANAGEMENT_EXECUTOR = ExecutorFactory.Managed
            .newSingleScheduledExecutorService(ClassUtils.getCanonicalName(ConfigExecutor.class),
                    new NameThreadFactory("com.viknix.tpm.config.CapacityManagement"));

    private static final ScheduledExecutorService ASYNC_NOTIFY_EXECUTOR = ExecutorFactory.Managed
            .newScheduledExecutorService(ClassUtils.getCanonicalName(ConfigExecutor.class), 100,
                    new NameThreadFactory("com.viknix.tpm.config.AsyncNotifyService"));

    private static final ScheduledExecutorService CONFIG_SUB_SERVICE_EXECUTOR = ExecutorFactory.Managed
            .newScheduledExecutorService(ClassUtils.getCanonicalName(ConfigExecutor.class),
                    ThreadUtils.getSuitableThreadCount(),
                    new NameThreadFactory("com.viknix.tpm.config.ConfigSubService"));

    private static final ScheduledExecutorService LONG_POLLING_EXECUTOR = ExecutorFactory.Managed
            .newSingleScheduledExecutorService(ClassUtils.getCanonicalName(ConfigExecutor.class),
                    new NameThreadFactory("com.viknix.tpm.config.LongPolling"));

    public static void scheduleConfigTask(Runnable command, long initialDelay, long delay, TimeUnit unit) {
        TIMER_EXECUTOR.scheduleWithFixedDelay(command, initialDelay, delay, unit);
    }

    public static void executeEmbeddedDump(Runnable runnable) {
        DUMP_EXECUTOR.execute(runnable);
    }

    public static void scheduleCorrectUsageTask(Runnable runnable, long initialDelay, long delay, TimeUnit unit) {
        CAPACITY_MANAGEMENT_EXECUTOR.scheduleWithFixedDelay(runnable, initialDelay, delay, unit);
    }

    public static void executeAsyncNotify(Runnable runnable) {
        ASYNC_NOTIFY_EXECUTOR.execute(runnable);
    }

    public static void scheduleAsyncNotify(Runnable command, long delay, TimeUnit unit) {
        ASYNC_NOTIFY_EXECUTOR.schedule(command, delay, unit);
    }

    public static int asyncNotifyQueueSize() {
        return ((ScheduledThreadPoolExecutor) ASYNC_NOTIFY_EXECUTOR).getQueue().size();
    }

    public static ScheduledExecutorService getConfigSubServiceExecutor() {
        return CONFIG_SUB_SERVICE_EXECUTOR;
    }

    public static void scheduleLongPolling(Runnable runnable, long initialDelay, long period, TimeUnit unit) {
        LONG_POLLING_EXECUTOR.scheduleWithFixedDelay(runnable, initialDelay, period, unit);
    }

    public static ScheduledFuture<?> scheduleLongPolling(Runnable runnable, long period, TimeUnit unit) {
        return LONG_POLLING_EXECUTOR.schedule(runnable, period, unit);
    }

    public static void executeLongPolling(Runnable runnable) {
        LONG_POLLING_EXECUTOR.execute(runnable);
    }

}
